package com.ylwl.datacenterdemo.aspect;

import com.ylwl.datacenterdemo.annotation.TimeConsuming;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect
@Component
public class TimeConsumingAspect {
    
    private static final Logger log = LoggerFactory.getLogger(TimeConsumingAspect.class);

    @Around("@annotation(com.ylwl.datacenterdemo.annotation.TimeConsuming)")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        
        // 获取方法信息
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        String methodName = method.getName();
        String className = joinPoint.getTarget().getClass().getSimpleName();
        
        // 获取注解信息
        TimeConsuming timeConsuming = method.getAnnotation(TimeConsuming.class);
        String description = timeConsuming.value();
        
        // 记录参数信息
        Object[] args = joinPoint.getArgs();
        
        String logPrefix = description.isEmpty() ? 
                String.format("%s.%s", className, methodName) : 
                String.format("%s.%s[%s]", className, methodName, description);
        
        log.info("开始执行 {}，参数: {}", logPrefix, args.length > 0 ? args[0] : "无");
        
        try {
            Object result = joinPoint.proceed();
            long endTime = System.currentTimeMillis();
            long duration = endTime - startTime;
            log.info("{} 执行完成，耗时: {} ms", logPrefix, duration);
            return result;
        } catch (Exception e) {
            long endTime = System.currentTimeMillis();
            long duration = endTime - startTime;
            log.error("{} 执行出错，耗时: {} ms", logPrefix, duration, e);
            throw e;
        }
    }
}